
// noise.js
// this is a simple library for rendering noise and clouds

function render_fill(d, red, green, blue, alpha) {
	var row = 0;
	var col = 0;
	var i = 0;
	var s = new Array();
	s[0] = 255 * alpha * red
	s[1] = 255 * alpha * green;
	s[2] = 255 * alpha * blue;
	var ra = 1 - alpha;
	var c;
	for (row = 0; row < d.height; ++row) {
		for (col = 0; col < d.width; ++col) {
			for (c = 0; c < 3; ++c) {
				d.data[i + c] = Math.floor(
					d.data[i + c] * ra + s[c]
				);
					
			}
			d.data[i + 3] = 255;
			i += 4;
		}
	}
}

function dice_grids(g) {
	var i = 0;
	var n = 1;

	var a = new Array();
	for (var i = 0; i < g.length; ++i) {
		dice_grid(g, a, n);
		n *=2;
	}
}

function make_grids(w, h, levels) {
	var i = 0;
	var nw = w - 1;
	var nh = h - 1;

	var o = new Array();

	if (nw < 1) { nw = 1; }
	if (nh < 1) { nh = 1; }

	for (i = 0; i < levels; ++i) {
		o.push(random_grid(nw + 1, nh + 1));
		nw *= 2; nh *= 2;
	}

	return o;
}

function render_grids(d, grids, alpha) {
	var i = 0;
	var a = alpha;
	for (i = 0; i < grids.length; ++i) {
		render_gradients(d, grids[i], a);
		a /=2;
	}
}

function render_clouds(d, levels, alpha) {
	render_grids(d, make_grids(1, 1, levels), alpha);
}

function random_grid(w, h) {
	var p = new Array();

	var row = 0;
	var col = 0;
	var c = 0;

	for (row = 0; row < h; ++row) {
		p[row] = new Array();
		for (col = 0; col < w; ++col) {
			p[row][col] = new Array();
			for (c = 0; c < 3; ++c) {
				p[row][col][c] = Math.random();
			}
		}
	}

	return p;
}

function render_gradients(d, p, alpha) {

	var col = 0;
	var row = 0;

	i = 0;
	var row_weight = 0;
	var row_section = 0;
	var col_weight = 0;
	var col_section = 0;

	for (row = 0; row < d.height; ++row) {
		row_weight = (p.length - 1) * row / d.height;
		row_section = Math.floor(row_weight);
		row_weight -= row_section;

		var c = 0;
		for (col = 0; col < d.width; ++col) {
			col_weight = (p[0].length - 1) * col / d.width;
			col_section = Math.floor(col_weight);
			col_weight -= col_section;

			p_lt = p[row_section][col_section];
			p_rt = p[row_section][col_section + 1];
			p_lb = p[row_section + 1][col_section];
			p_rb = p[row_section + 1][col_section + 1];

			for (c = 0; c < 3; ++c) {
				d.data[i + c] = Math.floor(
				255 * (
					(p_lt[c] * (1 - col_weight) +
					p_rt[c] * col_weight) * 
					(1 - row_weight) +
					(p_lb[c] * (1 - col_weight) +
					p_rb[c] * col_weight) * 
					row_weight
				) * alpha +
				d.data[i + c] * (1 - alpha)
				)
			}
			d.data[i + 3] = 255;
			i += 4;
		}
	}
}

